package net.bat.db;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;

import net.bat.service.HDDefault;

import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.jdbc.Work;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.type.IdentifierType;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

@SuppressWarnings("unchecked")

public class BaseDAOImpl extends HibernateDaoSupport implements BaseDAO {
	static HashMap<String,ClassMetadata> classMetas = new HashMap<String,ClassMetadata>();
	static String LM_CP;
	public static String getLM_CP() {
		return LM_CP;
	}
	public void setLM_CP(String lm_cp) {
		LM_CP = lm_cp;
	}
	public void executeSQL(final String queryString){
        HibernateTemplate tmpl = getHibernateTemplate();  
        tmpl.execute(new HibernateCallback() {  
            @Override  
            public Object doInHibernate(Session session)  
                throws HibernateException, SQLException {              	
                session.doWork(new Work(){
					@Override
					public void execute(Connection conn) throws SQLException {
						// TODO Auto-generated method stub		
						PreparedStatement pstat = conn.prepareStatement(queryString);  
						pstat.execute();  
					}  
                });
				return session;   
            }  
        });  				
	}
	public ClassMetadata getClassMeta(String cn){
		ClassMetadata cm = classMetas.get(cn);
		if(cm==null){
			org.hibernate.SessionFactory sf = getSessionFactory();
			cm=sf.getClassMetadata(cn);
			classMetas.put(cn, cm);
		}
		return cm;
	}
	public Object loadPO(String cn,String keyValue) throws Exception{
		ClassMetadata cm=getClassMeta(cn);		
		IdentifierType  it = (IdentifierType) cm.getIdentifierType();
		Object kt= it.stringToObject(keyValue.toString());
		return getHibernateTemplate().get(cn, (Serializable)kt);
	}
	public Object getDefaultObj(String cn){
		ClassMetadata cm=getClassMeta(cn);
		Object ro=cm.instantiate(null,EntityMode.POJO);
		return ro;
	}
	 public void save(Object object) {
	  getHibernateTemplate().save(object);
	 }

	 public void update(Object object) {
	  getHibernateTemplate().update(object);
	 }

	 public void updateByQuery(final String queryString,
	   final Object[] parameters) {
	  getHibernateTemplate().execute(new HibernateCallback() {
	   public Object doInHibernate(Session session) {
	    Query query = session.createQuery(queryString);
	    if (parameters != null) {
	     for (int i = 0; i < parameters.length; i++) {
	      query.setParameter(i, parameters[i]);
	     }
	    }
	    query.executeUpdate();
	    return null;
	   }
	  });
	 }

	 public void delete(Object object) {
	  getHibernateTemplate().delete(object);
	 }

	 public void delete(Class clazz, Serializable id) {
	  getHibernateTemplate().delete(load(clazz, id));
	 }

	 public Integer deleteAll(final Class clazz) {
	  return (Integer) getHibernateTemplate().execute(
	    new HibernateCallback() {
	     public Object doInHibernate(Session session) {
	      Query query = session.createQuery("delete "
	        + clazz.getName());
	      return new Integer(query.executeUpdate());
	     }
	    });
	 }

	 public List findAll(Class clazz) {
	  return getHibernateTemplate().find("from " + clazz.getName());
	 }

	 public Object load(Class clazz, Serializable id) {
	  return getHibernateTemplate().load(clazz, id);
	 }

	 public Object get(Class clazz, Serializable id) {
	  return getHibernateTemplate().get(clazz, id);
	 }

	 public List findByNamedQuery(final String queryName) {
	  return getHibernateTemplate().findByNamedQuery(queryName);
	 }

	 public List findByNamedQuery(final String queryName, final Object parameter) {
	  return getHibernateTemplate().findByNamedQuery(queryName, parameter);
	 }

	 public List findByNamedQuery(final String queryName,
	   final Object[] parameters) {
	  return getHibernateTemplate().findByNamedQuery(queryName, parameters);
	 }

	 public List find(final String queryString) {
	  return getHibernateTemplate().find(queryString);
	 }

	 public List find(final String queryString, final Object parameter) {
	  
	     return getHibernateTemplate().find(queryString, parameter);
	 
	  
	 }
	 
	 public List find(final String queryString, final Object[] parameters) {
	  return getHibernateTemplate().find(queryString, parameters);
	 }

    public List get(final String hql,  final int first, final int rownum){
    	  List result = (List)this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)throws SQLException, HibernateException {
						Query query= session.createQuery(hql);
						query.setFirstResult(first);
						query.setMaxResults(rownum);
					  	return query.list();
					}//end doInHibernate
				}//end HibernateCallback
			);//end executeFind	
		return result;     	
     }
	 public List findTop(final String queryString, int n) {
	  HibernateTemplate template = getHibernateTemplate();
	  template.setMaxResults(n);
	  List list = template.find(queryString);
	  template.setMaxResults(0);
	  return list;
	 }

	 public List findTop(final String queryString, final Object[] parameters,
	   int n) {
	  HibernateTemplate template = getHibernateTemplate();
	  template.setMaxResults(n);
	  List list = template.find(queryString, parameters);
	  template.setMaxResults(0);
	  return list;
	 }

	 public List findPageByQuery(final String queryString,
	   final Object[] parameters, final Page page) {
	  return (List) getHibernateTemplate().executeFind(
	    new HibernateCallback() {
	     public Object doInHibernate(Session session)
	       throws SQLException, HibernateException {
	      Query query = session.createQuery(queryString);
	      if (parameters != null) {
	       for (int i = 0; i < parameters.length; i++) {
	        query.setParameter(i, parameters[i]);
	       }
	      }
	      query.setFirstResult(page.getStart());
	      query.setMaxResults(page.getPageSize());
	      return query.list();
	     }
	    });
	 }

	 public Integer deleteByQuery(final String queryString,
	   final Object[] parameters) {
	  return (Integer) getHibernateTemplate().execute(
	    new HibernateCallback() {
	     public Object doInHibernate(Session session) {
	      Query query = session.createQuery(queryString);
	      if (parameters != null) {
	       for (int i = 0; i < parameters.length; i++) {
	        query.setParameter(i, parameters[i]);
	       }
	      }
	      return new Integer(query.executeUpdate());
	     }
	    });
	 }

	 public Object get(final String queryString, final Object[] parameters) {
	  List list = getHibernateTemplate().find(queryString, parameters);
	  if (list != null && !list.isEmpty()) {
	   return list.get(0);
	  }
	  return null;
	 }

	 public Object get(final String queryString, final Object parameter) {
	  if(getHibernateTemplate().find(queryString, parameter).isEmpty()){
	   return null;
	  }else{
	     return getHibernateTemplate().find(queryString, parameter).get(0);
	 
	  }
	  
	 }
	
	 public Integer getCountByQuery(String queryString, Object[] parameters) {
		 
		
	  return Integer.parseInt(getHibernateTemplate().find(
	    "select count(*) " + queryString, parameters).listIterator()
	    .next().toString());
	 }
	 
	 public void cleanSession(){
	  getHibernateTemplate().getSessionFactory(). getCurrentSession().clear();
	 }
	}
